home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Core / Sources / PascalString.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  18.8 KB  |  600 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // PascalString.cp 
  3. // Copyright © 1985-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __PASCALSTRING__
  7. #include "PascalString.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. // Toolbox
  13.  
  14. #ifndef __MEMORY__
  15. #include <Memory.h>
  16. #endif
  17.  
  18. // ANSI
  19.  
  20. #ifndef __LIMITS__
  21. #include <Limits.h>
  22. #endif
  23.  
  24. #if qDebugMsg
  25.     #ifndef __STDIO__
  26.     #include <stdio.h>
  27.     #endif
  28. #endif
  29.  
  30. #pragma segment Main
  31.  
  32. //----------------------------------------------------------------------------------------
  33. // static data members
  34. //----------------------------------------------------------------------------------------
  35. Handle CPascalStr::fgItl2Handle;
  36.  
  37. //========================================================================================
  38. // GLOBAL Functions
  39. //========================================================================================
  40.  
  41. //----------------------------------------------------------------------------------------
  42. // MABlockMove:
  43. //----------------------------------------------------------------------------------------
  44.  
  45. #if !qPowerPC && (UINT_MAX < ULONG_MAX)
  46. void MABlockMove(const void* srcPtr, void* destPtr, long byteCount)
  47. {
  48.     // We think size_t is at least a long, so we don't need a cast.
  49.     // If we get a compiler warning, we're in trouble. 
  50.     if (byteCount < UINT_MAX) // size_t could be an unsigned 16 bit value
  51.         ::memcpy(destPtr, srcPtr, byteCount);
  52.     else
  53.         BlockMoveData(srcPtr, destPtr, byteCount);
  54. }
  55. #endif
  56.  
  57. //----------------------------------------------------------------------------------------
  58. // MABlockMoveOverlap:
  59. //----------------------------------------------------------------------------------------
  60.  
  61. #if !qPowerPC && (UINT_MAX < ULONG_MAX)
  62. void MABlockMoveOverlap(const void* srcPtr, void* destPtr, long byteCount)
  63. {
  64.     // We think size_t is at least a long, so we don't need a cast.
  65.     // If we get a compiler warning, we're in trouble. 
  66.     if (byteCount < UINT_MAX) // size_t could be an unsigned 16 bit value
  67.         ::memmove(destPtr, srcPtr, byteCount);
  68.     else
  69.         BlockMoveData(srcPtr, destPtr, byteCount);
  70. }
  71. #endif
  72.  
  73. //========================================================================================
  74. // CLASS CCharStr
  75. //========================================================================================
  76. //----------------------------------------------------------------------------------------
  77. // CCharStr::CopyFrom
  78. //----------------------------------------------------------------------------------------
  79.  
  80. void CCharStr::CopyFrom(const unsigned char* str, unsigned char maxLength)
  81. {
  82.     size_t possibleLength = 0;
  83.     if (str)
  84.     {
  85.         possibleLength = str[0];
  86.         possibleLength = possibleLength < maxLength ? possibleLength : maxLength;
  87.     }
  88.  
  89.     MABlockMove(&str[1], this, possibleLength);
  90.     ((char*)this)[possibleLength] = 0;
  91. }
  92.  
  93. //----------------------------------------------------------------------------------------
  94. // CCharStr::CopyFrom
  95. //----------------------------------------------------------------------------------------
  96.  
  97. void CCharStr::CopyFrom(const char* str, size_t maxLength)
  98. {
  99.     size_t possibleLength = 0;
  100.     if (str)
  101.     {
  102.         possibleLength = strlen(str);
  103.         possibleLength = possibleLength < maxLength ? possibleLength : maxLength;
  104.     }
  105.  
  106.     MABlockMove(str, this, possibleLength);
  107.     ((char*)this)[possibleLength] = 0;
  108. }
  109.  
  110. //----------------------------------------------------------------------------------------
  111. // CCharStr::CopyFrom
  112. //----------------------------------------------------------------------------------------
  113.  
  114. void CCharStr::CopyFrom(const void* str, size_t forLength)
  115. {
  116.     //
  117.     // NOTE: there is _NO_ maxlength protection here, be careful!
  118.     // However, since Length() is an unsigned char
  119.     // its maximum value is kStr255Len anyways.
  120.     //
  121.     MABlockMove(str, this, forLength);
  122.     ((char*)this)[forLength] = 0;
  123. }
  124.  
  125. //========================================================================================
  126. // CLASS CPascalStr
  127. //========================================================================================
  128.  
  129. //----------------------------------------------------------------------------------------
  130. // CPascalStr::CopyFrom
  131. //----------------------------------------------------------------------------------------
  132.  
  133. void CPascalStr::CopyFrom(const unsigned char* str, unsigned char maxLength)
  134. {
  135.     unsigned char possibleLength = 0;
  136.     if (str)
  137.     {
  138.         possibleLength = str[0];
  139.         possibleLength = possibleLength < maxLength ? possibleLength : maxLength;
  140.     }
  141.  
  142.     Length() = possibleLength;
  143.     MABlockMove(&str[1], &(*this)[1], Length());
  144. }
  145.  
  146. //----------------------------------------------------------------------------------------
  147. // CPascalStr::CopyFrom
  148. //----------------------------------------------------------------------------------------
  149.  
  150. void CPascalStr::CopyFrom(const char* str, unsigned char maxLength)
  151. {
  152.     unsigned char possibleLength = 0;
  153.     if (str)
  154.     {
  155.         possibleLength = (unsigned char)strlen(str);
  156.         possibleLength = possibleLength < maxLength ? possibleLength : maxLength;
  157.     }
  158.  
  159.     Length() = possibleLength;
  160.     MABlockMove(str, &(*this)[1], Length());
  161.     
  162. }
  163.  
  164. //----------------------------------------------------------------------------------------
  165. // CPascalStr::CopyFrom
  166. //----------------------------------------------------------------------------------------
  167.  
  168. void CPascalStr::CopyFrom(const void* str, unsigned char forLength)
  169. {
  170.     //
  171.     // NOTE: there is _NO_ maxlength protection here, be careful!
  172.     // However, since Length() is an unsigned char
  173.     // its maximum value is kStr255Len anyways.
  174.     //
  175.     Length() = forLength;
  176.     MABlockMove(str, &(*this)[1], Length());
  177. }
  178.  
  179. //----------------------------------------------------------------------------------------
  180. // CPascalStr::CopyFrom
  181. //----------------------------------------------------------------------------------------
  182.  
  183. void CPascalStr::CopyFrom(const unsigned char* str)
  184. {
  185.     //
  186.     // NOTE: there is _NO_ maxlength protection here, be careful!
  187.     // However, since Length() is an unsigned char
  188.     // its maximum value is kStr255Len anyways.
  189.     //
  190.     Length() = str[0];
  191.     MABlockMove(&str[1], &(*this)[1], Length());
  192. }
  193.  
  194. //----------------------------------------------------------------------------------------
  195. // CPascalStr::CopyFrom
  196. //----------------------------------------------------------------------------------------
  197.  
  198. void CPascalStr::CopyFrom(const char* str)
  199. {
  200.     //
  201.     // NOTE: there is _NO_ maxlength protection here, be careful!
  202.     // However, since Length() is an unsigned char
  203.     // its maximum value is kStr255Len anyways.
  204.     //
  205.     Length() = strlen(str);
  206.     MABlockMove(str, &(*this)[1], Length());
  207. }
  208.  
  209. #if !(qPowerPC || qNeedsMC68020)
  210. //----------------------------------------------------------------------------------------
  211. // CPascalStr::CopyFrom
  212. //----------------------------------------------------------------------------------------
  213.  
  214. void CPascalStr::CopyFrom(unsigned long id)
  215. {
  216.     //
  217.     // NOTE: there is _NO_ maxlength protection here, be careful!
  218.     // However, since Length() is an unsigned char
  219.     // its maximum value is kStr255Len anyways.
  220.     //
  221.     Length() = sizeof(id);
  222.     MABlockMove(&id, &(*this)[1], Length());
  223. }
  224. #endif
  225.  
  226.  
  227. #if !(qPowerPC || qNeedsMC68020)
  228. //----------------------------------------------------------------------------------------
  229. // CPascalStr::CopyFrom
  230. //----------------------------------------------------------------------------------------
  231.  
  232. void CPascalStr::CopyFrom(unsigned short num)
  233. {
  234.     //
  235.     // NOTE: there is _NO_ maxlength protection here, be careful!
  236.     // However, since Length() is an unsigned char
  237.     // its maximum value is kStr255Len anyways.
  238.     //
  239.     Length() = sizeof(num);
  240.     MABlockMove(&num, &(*this)[1], Length());
  241. }
  242. #endif
  243.  
  244. //----------------------------------------------------------------------------------------
  245. // CPascalStr::CopyTo
  246. //----------------------------------------------------------------------------------------
  247.  
  248. void CPascalStr::CopyTo(unsigned char* str) const
  249. {
  250.     MABlockMove(&(*this)[0], str, Length() + 1);
  251. }
  252.  
  253. //----------------------------------------------------------------------------------------
  254. // CPascalStr::CopyTo
  255. //----------------------------------------------------------------------------------------
  256.  
  257. void CPascalStr::CopyTo(char* str) const
  258. {
  259.     MABlockMove(&(*this)[1], str, Length());
  260.     str[Length()] = 0;    // Add null terminations
  261. }
  262.  
  263. //----------------------------------------------------------------------------------------
  264. // CPascalStr::CopyTo
  265. //----------------------------------------------------------------------------------------
  266.  
  267. void CPascalStr::CopyTo(void* str) const
  268. {
  269.     MABlockMove(&(*this)[1], str, Length());
  270. }
  271. //----------------------------------------------------------------------------------------
  272. // CPascalStr::GetMaxLength:
  273. //----------------------------------------------------------------------------------------
  274.  
  275. unsigned char CPascalStr::GetMaxLength(unsigned char pos, unsigned char length) const
  276. {
  277.     short testLength = Length() - pos + kLengthByte;
  278.  
  279.     testLength = (length > testLength) ? testLength : length;
  280.  
  281.     if (testLength < 0)
  282.         testLength = 0;
  283.         
  284.     return (unsigned char)testLength;
  285. }
  286.  
  287. #if !(qPowerPC || qNeedsMC68020)
  288. //----------------------------------------------------------------------------------------
  289. // CPascalStr::ToULong
  290. //----------------------------------------------------------------------------------------
  291.  
  292. unsigned long CPascalStr::ToULong() const
  293. {
  294.     //
  295.     // NOTE: there is _NO_ maxlength protection here, be careful!
  296.     // However, since Length() is an unsigned char
  297.     // its maximum value is kStr255Len anyways.
  298.     //
  299.     unsigned long returnVal;
  300.     MABlockMove(&(*this)[1], &returnVal, sizeof(returnVal));
  301.     
  302.     return returnVal;
  303. }
  304. #endif
  305.  
  306. #if !(qPowerPC || qNeedsMC68020)
  307. //----------------------------------------------------------------------------------------
  308. // CPascalStr::ToULong
  309. //----------------------------------------------------------------------------------------
  310.  
  311. unsigned short CPascalStr::ToUShort() const
  312. {
  313.     //
  314.     // NOTE: there is _NO_ maxlength protection here, be careful!
  315.     // However, since Length() is an unsigned char
  316.     // its maximum value is kStr255Len anyways.
  317.     //
  318.     unsigned short returnVal;
  319.     MABlockMove(&(*this)[1], &returnVal, sizeof(returnVal));
  320.     
  321.     return returnVal;
  322. }
  323. #endif
  324.  
  325. //----------------------------------------------------------------------------------------
  326. // Definitions for relational string operators helpers
  327. //----------------------------------------------------------------------------------------
  328.  
  329. short CPascalStr::CPascalStrCompare(const CPascalStr& s1, const CPascalStr& s2)
  330. {
  331.     return ::CompareText(&s1[1], &s2[1], s1.Length(), s2.Length(), CPascalStr::fgItl2Handle);
  332. }
  333.  
  334. short CPascalStr::CPascalStrCompare(const CPascalStr& s1, const char* s2)
  335. {
  336.     return ::CompareText(&s1[1], s2, s1.Length(), s2 ? strlen(s2) : 0, CPascalStr::fgItl2Handle);
  337. }
  338.  
  339. short CPascalStr::CPascalStrCompare(const CPascalStr& s1, unsigned char ch)
  340. {
  341.     return ::CompareText(&s1[1], &ch, s1.Length(), 1, CPascalStr::fgItl2Handle);
  342. }
  343.  
  344. short CPascalStr::CPascalStrCompare(const char* s1, const CPascalStr& s2)
  345. {
  346.     return ::CompareText(s1, &s2[1], s1 ? strlen(s1) : 0, s2.Length(), CPascalStr::fgItl2Handle);
  347. }
  348.  
  349. short CPascalStr::CPascalStrCompare(unsigned char ch, const CPascalStr& s2)
  350. {
  351.     return ::CompareText(&ch, &s2[1], 1, s2.Length(), CPascalStr::fgItl2Handle);
  352. }
  353.  
  354.  
  355. //----------------------------------------------------------------------------------------
  356. // CPascalStr::operator+:
  357. //----------------------------------------------------------------------------------------
  358.  
  359. CStr255 operator+(const CPascalStr& s1, const CPascalStr& s2)
  360. {
  361.     CStr255 newStr;
  362.  
  363.     if (s1.Length() + s2.Length() > kStr255Len)
  364.         newStr.Length() = kStr255Len;
  365.     else
  366.         newStr.Length() = s1.Length() + s2.Length();
  367.         
  368.     MABlockMove(&s1[1], &newStr[1], s1.Length());
  369.     MABlockMove(&s2[1], &newStr[s1.Length() + kLengthByte], newStr.Length() - s1.Length());
  370.  
  371.     return newStr;
  372. }
  373.  
  374. //----------------------------------------------------------------------------------------
  375. // CPascalStr::operator+:
  376. //----------------------------------------------------------------------------------------
  377.  
  378. CStr255 operator+(const CPascalStr& s1, const char* s2)
  379. {
  380.     CStr255 newStr;
  381.     short s2Len = (s2) ? (short)(strlen(s2)) : 0;
  382.  
  383.     if (s1.Length() + s2Len > kStr255Len)
  384.         newStr.Length() = kStr255Len;
  385.     else
  386.         newStr.Length() = s1.Length() + s2Len;
  387.         
  388.     MABlockMove(&s1[1], &newStr[1], s1.Length());
  389.     MABlockMove(s2, &newStr[s1.Length() + kLengthByte], newStr.Length() - s1.Length());
  390.  
  391.     return newStr;
  392. }
  393.  
  394. //----------------------------------------------------------------------------------------
  395. // CPascalStr::operator+:
  396. //----------------------------------------------------------------------------------------
  397.  
  398. CStr255 operator+(const CPascalStr& s1, unsigned char ch)
  399. {
  400.     CStr255 newStr;
  401.     short s2Len = 1;
  402.  
  403.     if (s1.Length() + s2Len > kStr255Len)
  404.         newStr.Length() = kStr255Len;
  405.     else
  406.         newStr.Length() = s1.Length() + s2Len;
  407.         
  408.     MABlockMove(&s1[1], &newStr[1], s1.Length());
  409.     MABlockMove(&ch, &newStr[s1.Length() + kLengthByte], newStr.Length() - s1.Length());
  410.  
  411.     return newStr;
  412. }
  413.  
  414. //----------------------------------------------------------------------------------------
  415. // CPascalStr::operator+:
  416. //----------------------------------------------------------------------------------------
  417.  
  418. CStr255 operator+(const char* s1, const CPascalStr& s2)
  419. {
  420.     CStr255 newStr;
  421.     short s1Len = (s1) ? (short)(strlen(s1)) : 0;
  422.  
  423.     if (s1Len + s2.Length() > kStr255Len)
  424.         newStr.Length() = kStr255Len;
  425.     else
  426.         newStr.Length() = s1Len + s2.Length();
  427.         
  428.     MABlockMove(s1, &newStr[1], s1Len);
  429.     MABlockMove(&s2[1], &newStr[s1Len + kLengthByte], newStr.Length() - s1Len);
  430.  
  431.     return newStr;
  432. }
  433.  
  434. //----------------------------------------------------------------------------------------
  435. // CPascalStr::operator+:
  436. //----------------------------------------------------------------------------------------
  437.  
  438. CStr255 operator+(unsigned char ch, const CPascalStr& s2)
  439. {
  440.     CStr255 newStr;
  441.     short s1Len = 1;
  442.  
  443.     if (s1Len + s2.Length() > kStr255Len)
  444.         newStr.Length() = kStr255Len;
  445.     else
  446.         newStr.Length() = s1Len + s2.Length();
  447.         
  448.     MABlockMove(&ch, &newStr[1], s1Len);
  449.     MABlockMove(&s2[1], &newStr[s1Len + kLengthByte], newStr.Length() - s1Len);
  450.  
  451.     return newStr;
  452. }
  453.  
  454. //----------------------------------------------------------------------------------------
  455. // CPascalStr::Insert
  456. //----------------------------------------------------------------------------------------
  457.  
  458. void CPascalStr::Insert(const char* insStr, unsigned char insStrLength, unsigned char pos, unsigned char maxLength)
  459. {
  460.     if (insStr)
  461.     {
  462.         short shortPos = pos;
  463.         if (shortPos > Length() + 1)
  464.         {
  465. #if qDebugMsg
  466.             fprintf(stderr, "###CPascalStr::Insert: Insert position greater than length of CPascalStr.\n");
  467. #endif
  468.             if (Length() < maxLength)    
  469.                 shortPos = Length() + 1;
  470.         }
  471.     
  472. #if qDebugMsg
  473.         if ((short)Length() + insStrLength > maxLength)
  474.             fprintf(stderr, "### CPascalStr::Insert: CPascalStr truncated during insert call.\n");    
  475. #endif
  476.     
  477.         short usableLengthOfInsertString;
  478.         short endPosOfInsertString;
  479.         short usableLengthOfShiftedString;
  480.         
  481.         if (shortPos + insStrLength > maxLength)
  482.             usableLengthOfInsertString = maxLength - shortPos + 1;
  483.         else
  484.             usableLengthOfInsertString = insStrLength;
  485.         endPosOfInsertString = shortPos + usableLengthOfInsertString - 1;
  486.         
  487.         if ((endPosOfInsertString + 1) + (Length() - shortPos + 1) > maxLength)
  488.             usableLengthOfShiftedString = maxLength - endPosOfInsertString;
  489.         else
  490.             usableLengthOfShiftedString = Length() - shortPos + 1;
  491.             
  492.         MABlockMoveOverlap(&(*this)[shortPos], &(*this)[endPosOfInsertString + 1], usableLengthOfShiftedString);
  493.         MABlockMove(insStr, &(*this)[shortPos], usableLengthOfInsertString);
  494.         Length() = usableLengthOfShiftedString + endPosOfInsertString;
  495.     }
  496. }
  497.  
  498. //----------------------------------------------------------------------------------------
  499. // CPascalStr::Insert
  500. //----------------------------------------------------------------------------------------
  501.  
  502. void CPascalStr::Insert(const char* insStr, unsigned char pos, unsigned char maxLength)
  503. {
  504.     if (insStr)
  505.         Insert(insStr, strlen(insStr), pos, maxLength);
  506. }
  507.  
  508. //----------------------------------------------------------------------------------------
  509. // CPascalStr::Insert
  510. //----------------------------------------------------------------------------------------
  511.  
  512. void CPascalStr::Insert(const char* insStr, unsigned char pos)
  513. {
  514.     if (insStr)
  515.         Insert(insStr, strlen(insStr), pos, kStr255Len);
  516. }
  517.  
  518. //----------------------------------------------------------------------------------------
  519. // CPascalStr::Insert
  520. //----------------------------------------------------------------------------------------
  521.  
  522. void CPascalStr::Insert(const CPascalStr& insStr, unsigned char pos, unsigned char maxLength)
  523. {
  524.     Insert((const char*)&insStr[1], insStr.Length(), pos, maxLength);
  525. }
  526.  
  527. //----------------------------------------------------------------------------------------
  528. // CPascalStr::Insert
  529. //----------------------------------------------------------------------------------------
  530.  
  531. void CPascalStr::Insert(const CPascalStr& insStr, unsigned char pos)
  532. {
  533.     Insert((const char*)&insStr[1], insStr.Length(), pos, kStr255Len);
  534. }
  535.  
  536. //----------------------------------------------------------------------------------------
  537. // CPascalStr::Pos(char*):
  538. //----------------------------------------------------------------------------------------
  539.  
  540. unsigned char CPascalStr::Pos(const char* subStr, unsigned char startPos)
  541. {
  542.     char cStr[kStr255Len + 1];
  543.     char* ptr;
  544.     MABlockMove(&(*this)[1], cStr, Length());
  545.     cStr[Length()] = 0;
  546.     ptr = strstr((const char*)&cStr[startPos - 1], subStr);
  547.     return (ptr) ? (ptr - (const char*)cStr) + 1 : 0;
  548.  
  549. } // CPascalStr::Pos(char*)
  550.  
  551.  
  552. //----------------------------------------------------------------------------------------
  553. // CPascalStr::Pos(CPascalStr):
  554. //----------------------------------------------------------------------------------------
  555.  
  556. unsigned char CPascalStr::Pos(const CPascalStr& subStr, unsigned char startPos)
  557. {
  558.     char cStr[kStr255Len + 1];
  559.  
  560.     MABlockMove(&subStr[1], cStr, subStr.Length());
  561.     cStr[subStr.Length()] = 0;
  562.     return Pos(cStr, startPos);
  563.     
  564. } // CPascalStr::Pos(CPascalStr)
  565.  
  566. //----------------------------------------------------------------------------------------
  567. // CPascalStr::Delete
  568. //----------------------------------------------------------------------------------------
  569. void CPascalStr::Delete(unsigned char pos, unsigned char length)
  570. {
  571.     if ((pos > 0) && (length > 0) && (pos <= Length()))    // should also check that pos <= kMaxLength
  572.     {
  573.         if (pos + length > Length())
  574.             Length() = pos - 1;
  575.         else
  576.         {
  577.             MABlockMoveOverlap(&(*this)[pos + length], &(*this)[pos], Length() - (pos + length) + kLengthByte);
  578.             Length() -= length;
  579.         }
  580.     }
  581. } // CPascalStr::Delete
  582.  
  583.  
  584. //----------------------------------------------------------------------------------------
  585. // CPascalStr::SetItl2Handle
  586. //----------------------------------------------------------------------------------------
  587.  
  588. Handle CPascalStr::SetItl2Handle(Handle itsItl2Handle)
  589. {
  590.     Handle returnVal = fgItl2Handle;
  591.     fgItl2Handle = itsItl2Handle;
  592.     
  593.     return returnVal;
  594. }
  595.  
  596. //----------------------------------------------------------------------------------------
  597. // End of PascalString.cp
  598.  
  599. #pragma segment Inline
  600.